package jdbc;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.util.List;

/**
 * Apache-DBUtils使用
 */
@SuppressWarnings({"all"})
public class DBUtils_USE {

    public static void main(String[] args) {
        /*
            1.commons-dbutils 是 Apache 组织提供的一个开源JDBC工具类库，它是对JDBC的封装，使用dbutils能极大简化jdbc编码的工作量
            2.QueryRunner类：该类封装了SQL的执行，是线程安全的。可以实现增删改查、批处理
            3.使用QueryRunner类实现查询
            4.ResultSetHandler接口：该接口用于处理java.sql.ResultSet 将数据按要求转换为另一种形式
         */
        /*
            ArrayHandler：把结果集中的第一行数据转成对象数组
            ArrayListHandler：把结果集中的每一行数据都转成一个数组，再存放到List中
            BeanHandler：将结果集中的第一行数据封装到一个对应的JavaBean实例中
            BeanListHandler：将结果集中的每一行数据都封装到一个对应的JavaBean实例中，存放到List中
            ColumnListHandler：将结果集中某一列的数据存放到List中
            KeyedHandler(name)：将结果集中的每行数据都封装到Map里，再把这些map再存到一个map里，key为指定的key
            MapHandler：将结果集中的第一行数据封装到一个Map里，key是列名，value是对应的值
            MapListHandler：将结果集中的每一行数据都封装到一个Map里，然后再存放到List
         */
    }

    //使用Apache-DBUtils 工具类 + druid 完成对表的 crud 操作
    @Test
    public void testQueryMany() throws Exception {

        //1.得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用 DBUtils 类 和接口，先引入相关 jar，加入到Project
        //3.创建一个QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.就可以执行相关的方法，返回 ArrayList 结果集
        String sql = "select * from actor where id>?";
        /*
            1) query 方法就是执行一个sql语句，得到 resultSet ----封装---> ArrayList
            2) 返回集合
            3) connection：连接
            4) sql：执行的sql语句
            5) new BeanListHandler<>(Actor.class)：在将resultSet -> Actor对象 -> 封装到ArrayList
            底层使用反射机制 获取 Actor类的属性，然后进行封装。
            6) 1：给 sql 语句中的 ? 赋值。可以有多个值，因为底层是可变参数
            7) 底层的到的resultSet，会在query关闭，关闭PreparedStatement
         */
        List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);

        for (Actor actor : list) {
            System.out.println(actor);
        }
        //关闭资源
        JDBCUtilsByDruid.close(connection, null, null);

    }

    //使用Apache-DBUtils 工具类 + druid 完成 返回的结果是单行记录(单个对象)
    @Test
    public void testQuerySingle() throws Exception {
        //1.得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用 DBUtils 类 和接口，先引入相关 jar，加入到Project
        //3.创建一个QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.就可以执行相关的方法，返回 单个对象
        String sql = "select * from actor where id=?";
        // 返回BeanHandler
        Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
        System.out.println(actor);
        // 释放资源
        JDBCUtilsByDruid.close(connection, null, null);
    }

    //使用Apache-DBUtils 工具类 + druid 完成 返回的结果是单行单列记录，返回的就是Object
    @Test
    public void testScalar() throws Exception {
        //1.得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用 DBUtils 类 和接口，先引入相关 jar，加入到Project
        //3.创建一个QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.就可以执行相关的方法，返回 单个对象
        String sql = "select name from actor where id=?";
        // 因为返回的是单行单列记录，使用的Handler就是ScalarHandler()
        Object obj = queryRunner.query(connection, sql, new ScalarHandler(), 2);

        System.out.println(obj);
        // 释放资源
        JDBCUtilsByDruid.close(connection, null, null);
    }

    //使用Apache-DBUtils 工具类 + druid 完成 dml(update insert delete)
    @Test
    public void testDml() throws Exception {
        //1.得到连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        //2.使用 DBUtils 类 和接口，先引入相关 jar，加入到Project
        //3.创建一个QueryRunner
        QueryRunner queryRunner = new QueryRunner();
        //4.就可以执行相关的方法，返回 单个对象
//        String sql = "update actor set name = ? where id = ?";
//        String sql = "insert into actor values(null, ?, ?, ?, ?)";
        String sql = "delete from actor where id=?";
        // 因为返回的是单行单列记录，使用的Handler就是ScalarHandler()
        // 1)执行dml操作是 queryRunner.update()
        // 2)返回值是受影响的行数
        int affectedRow = queryRunner.update(connection, sql, "4");
        System.out.println(affectedRow > 0 ? "执行成功" : "执行没有影响到表");
        // 释放资源
        JDBCUtilsByDruid.close(connection, null, null);
    }

}
